﻿using System;
using System.Data;
using System.Configuration;
using TA.JSON;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
using TA.Turbo.Controls;

namespace TA.Turbo
{
	/// <summary>
	/// Styled element which also has an image and text label.
	/// </summary>
	public class StyledLabelElement : StyledElement
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public StyledLabelElement()
		{
			this.Text = "";
			this.Visible = true;
			this.TextImageRelation = TextImageRelation.ImageBeforeText;
			this.ImageAlt = "";
			this.ImageSrc = "";
		}
		#endregion
		#region PROPS
		/// <summary>
		/// Text to be shown in the element.
		/// </summary>
		[DefaultValue("")]
		[NotifyParentProperty(true)]
		public virtual string Text { get; set; }
		/// <summary>
		/// Url of the image to be shown in the element.
		/// </summary>
		[UrlProperty]
		[NotifyParentProperty(true)]
		[Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
		[DefaultValue("")]
		public string ImageSrc { get; set; }
		/// <summary>
		/// Alternate text to be shown in case image is not shown for any reason.
		/// </summary>
		[NotifyParentProperty(true)]
		[DefaultValue("")]
		public string ImageAlt { get; set; }
		/// <summary>
		/// Specifies the layout in which the text and the image are output.
		/// </summary>
		[NotifyParentProperty(true)]
		[DefaultValue(TextImageRelation.ImageBeforeText)]
		public virtual TextImageRelation TextImageRelation { get; set; }
		#endregion
		#region METHODS
		/// <summary>
		/// Instantiates controls described by this object in the specified container.
		/// </summary>
		/// <param name="container"></param>
		public virtual void InstantiateIn(Control container)
		{
			Image img = null;
			LiteralControl text = null;
			if (!string.IsNullOrEmpty(ImageSrc))
			{
				img = new Image
				{
					Src = ImageSrc
				};
			}
			if (!string.IsNullOrEmpty(Text))
			{
				text = new LiteralControl
				{
					Text = Text
				};
			}

			switch (TextImageRelation)
			{
				case TextImageRelation.ImageAboveText:
					if (img != null) container.Controls.Add(img);
					if (img != null && text != null) container.Controls.Add(new LiteralControl { Text = "<br/>" });
					if (text != null) container.Controls.Add(text);
					break;
				case TextImageRelation.ImageBeforeText:
					if (img != null) container.Controls.Add(img);
					if (text != null) container.Controls.Add(text);
					break;
				case TextImageRelation.TextAboveImage:
					if (text != null) container.Controls.Add(text);
					if (img != null && text != null) container.Controls.Add(new LiteralControl { Text = "<br/>" });
					if (img != null) container.Controls.Add(img);
					break;
				case TextImageRelation.TextBeforeImage:
					if (text != null) container.Controls.Add(text);
					if (img != null) container.Controls.Add(img);
					break;
			}
		}
		#endregion
		#endregion
		#region INTERNAL
		#region PROPS
		/// <summary>
		/// Gets true if <see cref="Text"/> is dirty.
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		protected virtual bool IsTextDirty
		{
			get
			{
				return !string.IsNullOrEmpty(this.Text);
			}
		}
		/// <summary>
		/// Gets true if <see cref="TextImageRelation"/> is dirty.
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		protected virtual bool IsTextImageRelationDirty
		{
			get
			{
				return this.TextImageRelation != TextImageRelation.ImageBeforeText;
			}
		}
		#endregion
		#region JSON
		/// <summary>
		/// IsDirty.
		/// </summary>
		[Browsable(false)]
		public override bool IsDirty
		{
			get
			{
				return
					base.IsDirty ||
					IsTextDirty ||
					!string.IsNullOrEmpty(this.ImageSrc) ||
					!string.IsNullOrEmpty(this.ImageAlt) ||
					IsTextImageRelationDirty;
			}
		}
		/// <summary>
		/// SerializeContents.
		/// </summary>
		/// <param name="jw"></param>
		public override void SerializeContents(JsonWriter jw)
		{
			base.SerializeContents(jw);

			if (IsTextDirty)
			{
				jw.PropertyName("T");
				jw.Value(this.Text);
			}
			if (IsTextImageRelationDirty)
			{
				jw.PropertyName("R");
				jw.Value(this.TextImageRelation);
			}
			if (!string.IsNullOrEmpty(this.ImageSrc))
			{
				jw.PropertyName("I");
				jw.Value(TPage.DoResolveUrl(this.ImageSrc));
			}

			if (!string.IsNullOrEmpty(this.ImageAlt))
			{
				jw.PropertyName("L");
				jw.Value(this.ImageAlt);
			}
		}
		/// <summary>
		/// DeserializeContent.
		/// </summary>
		/// <param name="jr"></param>
		/// <param name="propShortName"></param>
		public override void DeserializeContent(IJsonReader jr, string propShortName)
		{
			base.DeserializeContent(jr, propShortName);

			switch (propShortName)
			{
				case "I": this.ImageSrc = (string)jr.Value; break;
				case "T": this.Text = (string)jr.Value; break;
				case "R": this.TextImageRelation = (TextImageRelation)(long)jr.Value; break;
				case "L": this.ImageAlt = (string)jr.Value; break;
			}
		}
		/// <summary>
		/// Renders the contents describes by this element to HTML output.
		/// </summary>
		/// <param name="writer"></param>
		#endregion
		#region RENDER
		public virtual void Render(HtmlTextWriter writer)
		{
			switch (this.TextImageRelation)
			{
				case TextImageRelation.ImageBeforeText:
					RenderImage(writer);
					RenderText(writer);
					break;
				case TextImageRelation.TextBeforeImage:
					RenderText(writer);
					RenderImage(writer);
					break;
				case TextImageRelation.ImageAboveText:
					RenderImage(writer);
					if (!string.IsNullOrEmpty(this.ImageSrc) && this.IsTextDirty)
						writer.Write("<br/>");
					RenderText(writer);
					break;
				case TextImageRelation.TextAboveImage:
					RenderText(writer);
					if (!string.IsNullOrEmpty(this.ImageSrc) && this.IsTextDirty)
						writer.Write("<br/>");
					RenderImage(writer);
					break;
			}
		}
		/// <summary>
		/// Renders the text contents to HTML output.
		/// </summary>
		/// <param name="writer"></param>
		protected virtual void RenderText(HtmlTextWriter writer)
		{
			writer.Write(this.Text);
		}
		/// <summary>
		/// Renders the image contents to HTML output.
		/// </summary>
		/// <param name="writer"></param>
		protected virtual void RenderImage(HtmlTextWriter writer)
		{
			if (!string.IsNullOrEmpty(this.ImageSrc))
			{
				writer.AddAttribute(HtmlTextWriterAttribute.Src, TPage.DoResolveUrl(this.ImageSrc));
				writer.AddAttribute(HtmlTextWriterAttribute.Alt, this.ImageAlt);
				writer.RenderBeginTag(HtmlTextWriterTag.Img);

				writer.RenderEndTag();
			}
		}
		#endregion
		#endregion
	}
}